package com.cnap.multiclouldmgmt.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cnap.multiclouldmgmt.model.RepByPage;
import com.cnap.multiclouldmgmt.model.enums.K8sStatusEnum;
import com.cnap.multiclouldmgmt.model.k8sModels.K8sClusterModel;
import com.cnap.multiclouldmgmt.model.prometheusModels.PrometheusAlertModel;
import com.cnap.multiclouldmgmt.service.MultiCloudMgmtService;
import com.cnap.multiclouldmgmt.service.PrometheusService;
import com.cnap.multiclouldmgmt.util.CnapCloudMgmtConstants;
import com.cnap.multiclouldmgmt.util.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dyq
 *
 * prometheus查询支持
 * （1）CPU空闲率：
 * Avg by (instance) (irate(node_cpu_seconds_total{instance=~"****",  mode="idle"}[5m])) * 100
 * （2）磁盘使用率：
 * (100 - sum by (instance,mountpoint)
 * (node_filesystem_avail_bytes{instance=~"****",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"}) / sum by (instance,mountpoint)(node_filesystem_size_bytes
 * {instance=~"****",fstype!~"rootfs|selinuxfs|autofs|rpc_pipefs|tmpfs|udev|none|devpts|sysfs|debugfs|fuse.*"}) * 100)
 * （3）磁盘IO：
 * sum by (instance)
 * (irate(node_disk_io_time_seconds_total{instance=~"****"}[3m]))
 * （4）网络流量：
 * sum by (instance)
 * (irate(node_network_receive_bytes_total{instance=~"****",device!~"bond.*|lo"}[3m]))/1000/1000/125
 * （5）磁盘平均读写速率：
 * avg by (instance)(irate(node_disk_read_bytes_total
 * {instance=~"****",job="basic-server"}[5m])/1024/1024)
 * （6）网络平均上行（M）：
 * avg by (instance) (irate
 * (node_network_transmit_bytes_total{instance=~"****",job="basic-server"}[5m])/1024/1024)
 * （7）swap使用：
 * (node_memory_SwapTotal_bytes{instance=~"****",job="basic-server"}
 * - node_memory_SwapFree_bytes{instance=~"****",
 * job="basic-server"})/1024/1024
 * （8）CPU使用率：
 * 100 - (avg by (instance)
 * (irate(node_cpu{instance="xxx", mode="idle"}[5m])) * 100)
 * （9）磁盘大小：
 * node_filesystem_size_bytes{job="node_exporter",fstype=~"ext.?|xfs", mountpoint="/"}
 * （10）磁盘每秒读取（1h内）：
 * sum by (instance) (rate
 * (node_disk_reads_completed_total{job="node_exporter"}[1h]))
 * （11）cpu user模式占比：
 * sum by (instance)(rate(node_cpu_seconds_total
 * {job="node_exporter",mode="user"}[1m])) / sum by (instance)
 * (rate(node_cpu_seconds_total{job="node_exporter"}[1m]))
 * （12）cpu system模式占比：
 * sum by (instance)(rate
 * (node_cpu_seconds_total{job="node_exporter",mode="system"}[1m]))
 * / sum by (instance)(rate(node_cpu_seconds_total
 * {job="node_exporter"}[1m])
 *  NodeFilesystemSpaceFillingUp
 * （
 *
 * node  _ file  system  _ avail  _ bytes  { job=’ node-exporter  ‘，fstype！=’ ‘ }/node  _ file  system  _ size  _ bytes  { job=’ node-exporter  ‘，fstype！=”} * 100 15
 *
 * 和
 *
 * predict  _ linear(node  _ file  system  _ avail  _ bytes  { job=’ node-exporter  ‘，fstype！=”}[6h]，4*60*60) 0
 *
 * 和
 *
 * node  _ file  system  _ readonly  { job=’ node-exporter  ‘，fstype！=”}==0
 *
 * )
 *
 * 告警内容：集群{ { $ labels。群集} }/节点{ { $ labels。实例} }/设备{{ $labels.device  }}只剩下{{ printf  ‘%.2f’ $value  }}%的可用空间
 *
 * 1.2 NodeFilesystemAlmostOutOfSpace
 * （
 *
 * node  _ file  system  _ avail  _ bytes  { job=’ node-exporter  ‘，fstype！=’ ‘ }/node  _ file  system  _ size  _ bytes  { job=’ node-exporter  ‘，fstype！=”} * 100 3
 *
 * 和
 *
 * node  _ file  system  _ readonly  { job=’ node-exporter  ‘，fstype！=”}==0
 *
 * )
 *
 */
@Service("PrometheusServiceImpl")
public class PrometheusServiceImpl implements PrometheusService {

    private final static Logger LOGGER = LoggerFactory.getLogger(PrometheusServiceImpl.class);

    private static final String Prometheus_Port = "9090" ;

    private static final String GPU_Prometheus_Port = "30009" ;

    private static final String Prometheus_Potocol = "http://" ;

    private static final String Prometheus_Query_Path = "/api/v1/query";
    private static final String Prometheus_Query_Path_Range = "/api/v1/query_range";

    private static final String Prometheus_Node_Port = ":9100" ;

    private static final RestTemplate restTemplate = new RestTemplate();

    @Autowired
    private MultiCloudMgmtService multiCloudMgmtService;

    @Override
    public double getGpuMemFree(String k8sClusterIp) {
        String pSql = "DCGM_FI_DEV_FB_FREE";

        JSONArray pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        if (pResult == null){
            return 0;
        }

        double temp = 0;
        for (int i = 0; i < pResult.size();i++){

            try{
                temp +=
                        (Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getGpuMemTotal fail",e);
            }

            temp = temp/pResult.size();
        }

        double result = temp/1024d;
        LOGGER.warn("PrometheusServiceImpl getGpuMemFree ip={} result={}",k8sClusterIp,result);

        return result;

    }

    @Override
    public double getGpuMemUse(String k8sClusterIp) {
        //test ok
        String pSql = "DCGM_FI_DEV_FB_USED";

        JSONArray pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        if (pResult == null){
            return 0;
        }

        double temp = 0;
        for (int i = 0; i < pResult.size();i++){

            try{
                temp +=
                        (Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getGpuMemUse fail",e);
            }

            temp = temp/pResult.size();
        }

        double result = temp/1024d;
        LOGGER.warn("PrometheusServiceImpl getGpuMemUse ip={} result={}",k8sClusterIp,result);
        return result;
    }

    @Override
    public double getGpuPower(String k8sClusterIp) {
        //test ok
        String pSql = "DCGM_FI_DEV_POWER_USAGE";

        JSONArray pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        if (pResult == null){
            return 0;
        }

        double temp = 0;
        for (int i = 0; i < pResult.size();i++){

            try{
                temp +=
                        (Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getGpuPower fail",e);
            }

            temp = temp/pResult.size();
        }

        LOGGER.warn("PrometheusServiceImpl getGpuPower ip={} result={}",k8sClusterIp,temp);
        return temp;
    }

    //gpu使用率
    @Override
    public double getGpuUsage(String k8sClusterIp) {

        //test ok
        String pSql = "DCGM_FI_DEV_GPU_UTIL";

        JSONArray pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        if (pResult == null){
            return 0;
        }

        double temp = 0;
        for (int i = 0; i < pResult.size();i++){

            try{
                temp +=
                        (Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getGpuUsage fail",e);
            }

            temp = temp/pResult.size();
        }

        LOGGER.warn("PrometheusServiceImpl getGpuUsage ip={} result={}",k8sClusterIp,temp);
        return temp;
    }

    @Override
    public int getGpuTemp(String k8sClusterIp) {

        //test ok
        String pSql = "DCGM_FI_DEV_GPU_TEMP";

        JSONArray pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        if (pResult == null){
            return 0;
        }

        int temp = 0;
        for (int i = 0; i < pResult.size();i++){

            try{
                temp +=
                        (long)(Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getGpuTemp fail",e);
            }

            temp = temp/pResult.size();
        }

        LOGGER.warn("PrometheusServiceImpl getGpuTemp ip={} result={}",k8sClusterIp,temp);

        return temp;

    }

    /**
     *
     * @param pSql
     * @param userName
     * @param beginDate
     * @param endDate
     * @return
     * @throws Exception
     */
    @Override
    public List<PrometheusAlertModel> getPrometheusRangeData(String pSql, String userName, String beginDate, String endDate) throws Exception {

        List<PrometheusAlertModel> result = new ArrayList<>();

        LOGGER.warn("getPrometheusRangeData pSql={} userName={} beginDate={} endDate={}",pSql,userName,beginDate,endDate);


        int clusterNum = multiCloudMgmtService.getK8sClusterNum(null, null,userName);
        if (clusterNum == 0) {
            return result;
        }

        RepByPage<K8sClusterModel> k8sClusterModels =
                multiCloudMgmtService.getK8sClusterInfos(null, null, clusterNum, 1,userName);

        for (K8sClusterModel k8sClusterModel : k8sClusterModels.getResult()) {

            if (!StringUtils.equals(k8sClusterModel.getStatus(), K8sStatusEnum.Running.getChineseDescribe())){
                continue;
            }

            LOGGER.warn("getPrometheusRangeData k8sClusterIp={}",k8sClusterModel.getK8sClusterIp());

            JSONArray pResult = null;
            if (!StringUtils.endsWithIgnoreCase(k8sClusterModel.getK8sClusterName(),CnapCloudMgmtConstants.ARCH_GPU)) {

                pResult = queryPrometheusRange(k8sClusterModel.getK8sClusterIp(), pSql,
                        DateUtils.changeDateFormatYYYYMMDDHHMMToTimestamp(beginDate),
                        DateUtils.changeDateFormatYYYYMMDDHHMMToTimestamp(endDate));
            }else{

                pResult = queryPrometheusRangeGpu(k8sClusterModel.getK8sClusterIp(), pSql,
                        DateUtils.changeDateFormatYYYYMMDDHHMMToTimestamp(beginDate),
                        DateUtils.changeDateFormatYYYYMMDDHHMMToTimestamp(endDate));
            }

            if ((pResult == null)||(pResult.size() <= 0)){
                continue;
            }

            for (int i = 0; i < pResult.size();i++){

                PrometheusAlertModel prometheusAlertModel = new PrometheusAlertModel();
                prometheusAlertModel.setCreateTime(LocalDateTime.now());
                prometheusAlertModel.setpSql(pSql);

                JSONObject metricJsonObj = pResult.getJSONObject(i).getJSONObject("metric");
                prometheusAlertModel.setJob(
                        (metricJsonObj.getString("job") != null)?metricJsonObj.getString("job"):"");
                prometheusAlertModel.setInstance(
                        (metricJsonObj.getString("instance") != null)?
                                metricJsonObj.getString("instance"):"");
                prometheusAlertModel.setMetricMsg(metricJsonObj.toJSONString());
                //有可能metric为空，那就吧这些值手动设置为其他的东西
                //资源名称
                if (StringUtils.isEmpty(prometheusAlertModel.getInstance())){
                    prometheusAlertModel.setInstance(k8sClusterModel.getK8sClusterName());
                    prometheusAlertModel.setMetricMsg(
                            pSql);
                }
                //资源类型
                if (StringUtils.isEmpty(prometheusAlertModel.getJob())){
                    prometheusAlertModel.setJob("cluster,node");
                }
                prometheusAlertModel.setCloudVendor(k8sClusterModel.getCloudVendor());
                prometheusAlertModel.setK8sClusterIp(k8sClusterModel.getK8sClusterIp());
                prometheusAlertModel.setK8sClusterName(k8sClusterModel.getK8sClusterName());
                prometheusAlertModel.setCreateUser(k8sClusterModel.getCreateUser());

                result.add(prometheusAlertModel);
            }

        }

        return result;
    }

    @Override
    public long getNodeDiskTotalToB(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }

        String pSql = String.format("node_filesystem_size_bytes{instance=\"%s\",mountpoint=\"/\",fstype!=\"rootfs\"}",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;
        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)){

            pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        }else{
            pResult =  queryPrometheus(k8sClusterIp,pSql);

        }
        if (pResult == null){
            return 0L;
        }

        long totalNetIOPS = 0l;
        for (int i = 0; i < pResult.size();i++){

            try{
                totalNetIOPS +=
                        (long)(Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getNodeNetIOPS fail",e);
            }
        }
        return totalNetIOPS;
    }

    /**
     *
     * @param k8sClusterIp
     * @param nodeIp
     * @return
     *
     */
    @Override
    public double getNodeDiskThroughputByMbPerS(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }
        
        String pSql = String.format("irate(node_disk_written_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port)
                        +  String.format("+ irate(node_disk_read_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;

        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)){
            pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        }else {
            pResult = queryPrometheus(k8sClusterIp,pSql);
        }


        if (pResult == null){
            return 0d;
        }

        double totalDisThroughput = 0d;
        for (int i = 0; i < pResult.size();i++){
            try {
                totalDisThroughput += Double.parseDouble((String) pResult.getJSONObject(i).getJSONArray("value").get(1));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl totalDisThroughput fail",e);
            }
        }

        //得到的是Bytes/s 换成MB/s
        return totalDisThroughput/1024/1024;
    }

    /**
     *
     * @param k8sClusterIp
     * @param nodeIp
     * @return
     */
    @Override
    public long getNodeDiskIOPS(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }

        String pSql = String.format("irate(node_disk_reads_completed_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port)
                +  String.format("+ irate(node_disk_writes_completed_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;
        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)) {

            pResult = queryPrometheusGpu(k8sClusterIp, pSql);
        }else {

            pResult =queryPrometheus(k8sClusterIp, pSql);

        }
        if (pResult == null){
            return 0L;
        }

        long totalDiskIOPS = 0L;
        for (int i = 0; i < pResult.size();i++){
            try{
                totalDiskIOPS +=
                        (long)(Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getNodeDiskIOPS fail",e);
            }
        }
        return totalDiskIOPS;
    }

    /**
     * 
     * @param k8sClusterIp
     * @param nodeIp
     * @return
     */
    @Override
    public double getNodeNetBandwidthBybps(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }

        String pSql = String.format("irate(node_network_transmit_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port)
                +  String.format("+ irate(node_network_receive_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;
        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)){
            pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        }else {
            pResult = queryPrometheus(k8sClusterIp,pSql);
        }

        if (pResult == null){
            return 0L;
        }

        double totalNetBandwidth = 0d;
        for (int i = 0; i < pResult.size();i++){
            try{
                totalNetBandwidth +=
                        Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getNodeNetBandwidthBybps fail",e);
            }
        }
        return totalNetBandwidth;
    }

    /**
     *
     * @param k8sClusterIp
     * @param nodeIp
     * @return
     */
    @Override
    public long getNodeNetIOPS(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }

        String pSql = String.format("irate(node_network_transmit_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port)
                +  String.format("+ irate(node_network_receive_bytes_total{instance=\"%s\"}[5m])",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;

        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)){
            pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        }else {
            pResult = queryPrometheus(k8sClusterIp,pSql);
        }
        if (pResult == null){
            return 0L;
        }

        long totalNetIOPS = 0l;
        for (int i = 0; i < pResult.size();i++){
            try{
                totalNetIOPS +=
                        (long)(Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getNodeNetIOPS fail",e);
            }
        }
        return totalNetIOPS;
    }

    /**
     *
     * @param k8sClusterIp
     * @param nodeIp
     * @return
     */
    @Override
    public long getNodeDiskFreeUnitB(String k8sClusterIp, String nodeIp,String arch) {

        if (StringUtils.equals(k8sClusterIp,"172.17.4.83")){
            return 67;
        }

        String pSql = String.format("node_filesystem_free_bytes{instance=\"%s\",mountpoint=\"/\"}",nodeIp+Prometheus_Node_Port);

        JSONArray pResult = null;

        if (StringUtils.equalsIgnoreCase(arch,CnapCloudMgmtConstants.ARCH_GPU)){
            pResult = queryPrometheusGpu(k8sClusterIp,pSql);
        }else {
            pResult = queryPrometheus(k8sClusterIp,pSql);
        }
        if (pResult == null){
            return 0L;
        }

        long totalNetIOPS = 0l;
        for (int i = 0; i < pResult.size();i++){

            try{
                totalNetIOPS +=
                        (long)(Double.parseDouble((String)pResult.getJSONObject(i).getJSONArray("value").get(1)));
            }catch (Exception e){
                LOGGER.error("PrometheusServiceImpl getNodeNetIOPS fail",e);
            }
        }
        return totalNetIOPS;
    }

    /**
     *
     * @param k8sClusterIp
     * @param pSql
     * @return
     */
    private JSONArray queryPrometheusGpu(String k8sClusterIp, String pSql) {

        String encodePsql = null;
        try {
            encodePsql = URLEncoder.encode(pSql, "utf-8");
        } catch (Exception e) {
            LOGGER.error("queryPrometheusGpu encode error for string: {}, return none", pSql);
            return null;
        }

        UriComponentsBuilder builder = UriComponentsBuilder
                .fromHttpUrl(Prometheus_Potocol + k8sClusterIp + ":" + GPU_Prometheus_Port + Prometheus_Query_Path)
                .queryParam("query", encodePsql);

        String reponse = null;
        if (StringUtils.contains(k8sClusterIp, CnapCloudMgmtConstants.TEST_ADMIN)) {
            reponse = k8sClusterIp.replace(CnapCloudMgmtConstants.TEST_ADMIN,"");
        }else{
            reponse = restTemplate.getForObject(builder.build(true).toUri(),String.class);
        }


        if (StringUtils.isEmpty(reponse)) {
            LOGGER.warn("queryPrometheusGpu result is empty psql={}",pSql);
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(reponse);
        if ((jsonObject.getJSONObject("data") == null)
                || (jsonObject.getJSONObject("data").getJSONArray("result") == null)){

            return null;
        }

        JSONArray result = jsonObject.getJSONObject("data").getJSONArray("result");
        if (result.size() <= 0) {
            //打印过多，不让进行展示
            //LOGGER.error("queryPrometheus no result pSql={} respose={}",
            //      pSql,reponse);
            return null;
        }

        return result;
    }

    /**
     *
     * @param k8sClusterIp
     * @param pSql
     * @return
     */
    private JSONArray queryPrometheus(String k8sClusterIp, String pSql) {

        String encodePsql = null;
        try {
            encodePsql = URLEncoder.encode(pSql, "utf-8");
        } catch (Exception e) {
            LOGGER.error("PrometheusServiceImpl encode error for string: {}, return none", pSql);
            return null;
        }

        UriComponentsBuilder builder = UriComponentsBuilder
                .fromHttpUrl(Prometheus_Potocol + k8sClusterIp + ":" + Prometheus_Port + Prometheus_Query_Path)
                .queryParam("query", encodePsql);

        String reponse = null;
        if (StringUtils.contains(k8sClusterIp, CnapCloudMgmtConstants.TEST_ADMIN)) {
            reponse = k8sClusterIp.replace(CnapCloudMgmtConstants.TEST_ADMIN,"");
        }else{
            reponse = restTemplate.getForObject(builder.build(true).toUri(),String.class);
        }


        if (StringUtils.isEmpty(reponse)) {
            LOGGER.warn("queryPrometheus result is empty psql={}",pSql);
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(reponse);
        if ((jsonObject.getJSONObject("data") == null)
                || (jsonObject.getJSONObject("data").getJSONArray("result") == null)){

            return null;
        }

        JSONArray result = jsonObject.getJSONObject("data").getJSONArray("result");
        if (result.size() <= 0) {
            //打印过多，不让进行展示
            //LOGGER.error("queryPrometheus no result pSql={} respose={}",
              //      pSql,reponse);
            return null;
        }

        return result;
    }

    /**
     *
     * @param k8sClusterIp
     * @param pSql
     * @param beginDate
     * @param endDate
     * @return
     * @throws Exception
     */
    private JSONArray queryPrometheusRangeGpu(String k8sClusterIp, String pSql, long beginDate, long endDate) throws Exception {

        String encodePsql = null;
        long encodeStartTime = 0;
        long encodeEndTime = 0;
        try {

            encodePsql = URLEncoder.encode(pSql, "utf-8");
            encodeStartTime = beginDate/1000;
            encodeEndTime = endDate/1000;


        } catch (Exception e) {
            LOGGER.error("queryPrometheusRangeGpu encode error for string: {}, return none", pSql);
            return null;
        }

        //时间间隔的秒数
        int timeSeconds = DateUtils.countSecondsBetweenTwoDate(beginDate,endDate);
        //步长
        int step = Math.max(3,timeSeconds/8000);

        UriComponentsBuilder builder = UriComponentsBuilder
                .fromHttpUrl(Prometheus_Potocol + k8sClusterIp + ":" + GPU_Prometheus_Port + Prometheus_Query_Path_Range)
                .queryParam("query", encodePsql)
                .queryParam("start",encodeStartTime)
                .queryParam("end",encodeEndTime)
                .queryParam("step",step);

        String reponse = null;
        if (StringUtils.contains(k8sClusterIp, CnapCloudMgmtConstants.TEST_ADMIN)) {
            reponse = k8sClusterIp.replace(CnapCloudMgmtConstants.TEST_ADMIN,"");
        }else{
            String url = builder.build(true).toUri().toURL().toString();
            reponse = restTemplate.getForObject(builder.build(true).toUri(),String.class);
        }


        if (StringUtils.isEmpty(reponse)) {
            LOGGER.warn("queryPrometheusRangeGpu result is empty psql={}",pSql);
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(reponse);

        if (!StringUtils.equals("success", (String) jsonObject.get("status"))){
            throw new Exception("查询语句异常");
        }

        if ((jsonObject.getJSONObject("data") == null)
                || (jsonObject.getJSONObject("data").getJSONArray("result") == null)){

            return null;
        }

        return jsonObject.getJSONObject("data").getJSONArray("result");
    }

    /**
     *
     * @param k8sClusterIp
     * @param pSql
     * @param beginDate
     * @param endDate
     * @return
     * @throws Exception
     */
    private JSONArray queryPrometheusRange(String k8sClusterIp, String pSql, long beginDate, long endDate) throws Exception {

        String encodePsql = null;
        long encodeStartTime = 0;
        long encodeEndTime = 0;
        try {

            encodePsql = URLEncoder.encode(pSql, "utf-8");
            encodeStartTime = beginDate/1000;
            encodeEndTime = endDate/1000;


        } catch (Exception e) {
            LOGGER.error("PrometheusServiceImpl encode error for string: {}, return none", pSql);
            return null;
        }

        //时间间隔的秒数
        int timeSeconds = DateUtils.countSecondsBetweenTwoDate(beginDate,endDate);
        //步长
        int step = Math.max(3,timeSeconds/8000);

        UriComponentsBuilder builder = UriComponentsBuilder
                .fromHttpUrl(Prometheus_Potocol + k8sClusterIp + ":" + Prometheus_Port + Prometheus_Query_Path_Range)
                    .queryParam("query", encodePsql)
                    .queryParam("start",encodeStartTime)
                    .queryParam("end",encodeEndTime)
                    .queryParam("step",step);

        String reponse = null;
        if (StringUtils.contains(k8sClusterIp, CnapCloudMgmtConstants.TEST_ADMIN)) {
            reponse = k8sClusterIp.replace(CnapCloudMgmtConstants.TEST_ADMIN,"");
        }else{
            String url = builder.build(true).toUri().toURL().toString();
            reponse = restTemplate.getForObject(builder.build(true).toUri(),String.class);
        }


        if (StringUtils.isEmpty(reponse)) {
            LOGGER.warn("queryPrometheusRange result is empty psql={}",pSql);
            return null;
        }

        JSONObject jsonObject = JSONObject.parseObject(reponse);

        if (!StringUtils.equals("success", (String) jsonObject.get("status"))){
            throw new Exception("查询语句异常");
        }

        if ((jsonObject.getJSONObject("data") == null)
                || (jsonObject.getJSONObject("data").getJSONArray("result") == null)){

            return null;
        }

        return jsonObject.getJSONObject("data").getJSONArray("result");
    }
}
